package PrjWsMQ

import (
	"errors"
	"io/ioutil"
	"time"

	"golang.org/x/net/websocket"
)

const (
	WS_MESSAGE_TEXT          = 1
	WS_MESSAGE_BINARY        = 2
	WS_MESSAGE_CLOSE         = 0x08
	WS_MESSAGE_PING          = 0x09
	WS_MESSAGE_PONG          = 0x0A
	MQ_CHANNEL_CMD    string = "/cmd"
)

var (
	buf_spliter = []byte{0x0A}
)

type WsConnEx struct {
	websocket.Conn
	LastRecvT time.Time
}

func WrapperWsConnEx(conn *websocket.Conn) *WsConnEx {
	rval := &WsConnEx{Conn: *conn, LastRecvT: time.Now()}
	return rval
}

func (this *WsConnEx) CheckTimeOut(timeout time.Duration) bool {
	return time.Now().Sub(this.LastRecvT) > timeout
}

func ReceiveMessage(conn *WsConnEx) (msgtype byte, msg []byte, err error) {
again:
	frame, err := conn.NewFrameReader()
	if err != nil {
		return 0, nil, err
	}
	conn.LastRecvT = time.Now()
	frame, err = conn.HandleFrame(frame)
	if err != nil {
		return 0, nil, err
	}
	if frame == nil {
		goto again
	}
	maxPayloadBytes := conn.MaxPayloadBytes
	if maxPayloadBytes == 0 {
		maxPayloadBytes = websocket.DefaultMaxPayloadBytes
	}
	payloadType := frame.PayloadType()
	data, err := ioutil.ReadAll(frame)
	if err != nil {
		return 0, nil, err
	}
	return payloadType, data, err
}

func SendWsMessage(conn *WsConnEx, msgtype byte, msg []byte) error {
	if conn == nil {
		return errors.New("尚未建立连接")
	}
	writer, err := conn.NewFrameWriter(msgtype)
	if err != nil {
		return err
	}
	_, err = writer.Write(msg)
	return err
}

func SendWsPING(conn *WsConnEx) error {
	if conn == nil {
		return errors.New("尚未建立连接")
	}

	writer, err := conn.NewFrameWriter(websocket.PingFrame)
	if err != nil {
		return err
	}
	_, err = writer.Write([]byte{})
	return err
}

func ReceiveMessageEx(conn *websocket.Conn) (msgtype byte, msg []byte, err error) {
again:
	frame, err := conn.NewFrameReader()
	if err != nil {
		return 0, nil, err
	}
	frame, err = conn.HandleFrame(frame)
	if err != nil {
		return 0, nil, err
	}
	if frame == nil {
		goto again
	}
	maxPayloadBytes := conn.MaxPayloadBytes
	if maxPayloadBytes == 0 {
		maxPayloadBytes = websocket.DefaultMaxPayloadBytes
	}
	payloadType := frame.PayloadType()
	data, err := ioutil.ReadAll(frame)
	if err != nil {
		return 0, nil, err
	}
	return payloadType, data, err
}

func SendWsMessageEx(conn *websocket.Conn, msgtype byte, msg []byte) error {
	if conn == nil {
		return errors.New("尚未建立连接")
	}
	writer, err := conn.NewFrameWriter(msgtype)
	if err != nil {
		return err
	}
	_, err = writer.Write(msg)
	return err
}

func SendWsPINGEx(conn *websocket.Conn) error {
	if conn == nil {
		return errors.New("尚未建立连接")
	}

	writer, err := conn.NewFrameWriter(websocket.PingFrame)
	if err != nil {
		return err
	}
	_, err = writer.Write([]byte{})
	return err
}
